package scatter.identifier.rest.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import scatter.common.rest.controller.BaseAddUpdateQueryFormController;
import scatter.common.rest.exception.BusinessException;
import scatter.identifier.pojo.form.UpdatePasswordForm;
import scatter.identifier.rest.IdentifierConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
import org.springframework.web.bind.annotation.RestController;
import scatter.common.rest.controller.BaseAddUpdateQueryFormController;
import scatter.identifier.pojo.po.IdentifierPwd;
import scatter.identifier.pojo.vo.IdentifierPwdVo;
import scatter.identifier.pojo.form.IdentifierPwdAddForm;
import scatter.identifier.pojo.form.IdentifierPwdUpdateForm;
import scatter.identifier.pojo.form.IdentifierPwdPageQueryForm;
import scatter.identifier.rest.service.IIdentifierPwdService;

import javax.validation.Valid;
/**
 * <p>
 * 用户密码表 前端控制器
 * </p>
 *
 * @author yw
 * @since 2020-12-10
 */
@Slf4j
@Api(tags = "用户密码相关接口")
@RestController
@RequestMapping(IdentifierConfiguration.CONTROLLER_BASE_PATH + "/identifier-pwd")
public class IdentifierPwdController extends BaseAddUpdateQueryFormController<IdentifierPwd, IdentifierPwdVo, IdentifierPwdAddForm, IdentifierPwdUpdateForm, IdentifierPwdPageQueryForm> {


    @Autowired
    private IIdentifierPwdService iIdentifierPwdService;

    // 该bean如果放在scatter.identifier.rest.service.impl.IdentifierPwdServiceImpl中注入，会有循环依赖问题，提到这里来
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Value("${scatter.identifier.reset-password:123456}")
    private String resetPassword;

     @Override
	 @ApiOperation("添加用户密码")
     @PreAuthorize("hasAuthority('IdentifierPwd:add')")
     @PostMapping
     @ResponseStatus(HttpStatus.CREATED)
     public IdentifierPwdVo add(@RequestBody @Valid IdentifierPwdAddForm addForm) {
         return super.add(addForm);
     }

     @Override
	 @ApiOperation("根据ID查询用户密码")
     @PreAuthorize("hasAuthority('IdentifierPwd:queryById')")
     @GetMapping("/{id}")
     @ResponseStatus(HttpStatus.OK)
     public IdentifierPwdVo queryById(@PathVariable String id) {
         return super.queryById(id);
     }

     @Override
	 @ApiOperation("根据ID删除用户密码")
     @PreAuthorize("hasAuthority('IdentifierPwd:deleteById')")
     @DeleteMapping("/{id}")
     @ResponseStatus(HttpStatus.NO_CONTENT)
     public boolean deleteById(@PathVariable String id) {
         return super.deleteById(id);
     }

     @Override
	 @ApiOperation("根据ID更新用户密码")
     @PreAuthorize("hasAuthority('IdentifierPwd:update')")
     @PutMapping
     @ResponseStatus(HttpStatus.CREATED)
     public IdentifierPwdVo update(@RequestBody @Valid IdentifierPwdUpdateForm updateForm) {
         return super.update(updateForm);
     }

    @Override
	@ApiOperation("不分页查询用户密码")
    @PreAuthorize("hasAuthority('IdentifierPwd:getList')")
    @GetMapping("/getList")
    @ResponseStatus(HttpStatus.OK)
    public List<IdentifierPwdVo> getList(IdentifierPwdPageQueryForm listPageForm) {
         return super.getList(listPageForm);
    }

    @Override
	@ApiOperation("分页查询用户密码")
    @PreAuthorize("hasAuthority('IdentifierPwd:getPage')")
    @GetMapping("/getPage")
    @ResponseStatus(HttpStatus.OK)
    public IPage<IdentifierPwdVo> getPage(IdentifierPwdPageQueryForm listPageForm) {
         return super.getPage(listPageForm);
    }


    /**
     * 该重置密码会将用户所有密码数据重置为同一个
     * @param userId
     * @return
     */
    @ApiOperation("重置用户密码")
    @PreAuthorize("hasAuthority('IdentifierPwd:resetUserPwd')")
    @PostMapping("/resetUserPwd/{userId}")
    @ResponseStatus(HttpStatus.CREATED)
    public boolean resetUserPwd(@PathVariable String userId) {
        boolean r = iIdentifierPwdService.updatePasswordByUserId(userId,getEncodedPassword());
        if (r) {
            log.info("用户全部密码已重置为：{}，userId={}",resetPassword,userId);

            return r;
        }
        // 重置失败，尝试获取数据查找原因
        List<IdentifierPwd> byUserId = iIdentifierPwdService.getByUserId(userId);
        // 如果用户无密码信息
        if (isEmpty(byUserId)) {
            throw new BusinessException("密码重置失败，该用户无密码数据");
        }
        throw new BusinessException("密码重置失败");
    }
    @ApiOperation("重置单个密码")
    @PreAuthorize("hasAuthority('IdentifierPwd:resetIdentifierPwd')")
    @PostMapping("/resetIdentifierPwd/{identifierId}")
    @ResponseStatus(HttpStatus.CREATED)
    public boolean resetIdentifierPwd(@PathVariable String identifierId ) {
        boolean r = iIdentifierPwdService.updatePasswordByIdentifierId(identifierId,getEncodedPassword());
        if (r) {
            log.info("用户单个 identifier 密码已重置为：{}，identifierId={}",resetPassword,identifierId);
            return r;
        }
        // 重置失败，尝试获取数据查找原因
        List<IdentifierPwd> byUserId = iIdentifierPwdService.getByIdentifierIds(newArrayList(identifierId));
        // 如果用户无密码信息
        if (isEmpty(byUserId)) {
            throw new BusinessException("密码重置失败，该用户标识无密码数据");
        }
        throw new BusinessException("密码重置失败");
    }

    /**
     * 获取加密后的密码
     * @return
     */
    private String getEncodedPassword() {
         return passwordEncoder.encode(resetPassword);
    }
}
